#ifndef SUBSCRIBER_H
#define SUBSCRIBER_H
#include "Thread.h"
#include <assert.h>
#include <google/protobuf/message.h>
#include <stdio.h>
#include <map>
#include <vector>

  class Subscriber : public Thread
  {
    public:
      Subscriber();
      virtual ~Subscriber();

      class DataReader {
        public:
          virtual void incomingMessage(const void* data, int len) = 0;
      };
      
      template <class T>
      class DataReaderTemplate : public DataReader
      {
        public:
          DataReaderTemplate()
          {
          }
      
          void incomingMessage(const void* data, int len)
          {
            assert(data);
            T msg;
            std::string S((char*)data,len);
            msg.ParseFromString(S);
            handle(msg);
          }
      
          virtual void handle(T& msg) = 0;
      };

      void registerHandler(::google::protobuf::Message& msg, DataReader& reader);
      void unregister();
      void unregisterHandler(::google::protobuf::Message& msg, DataReader& reader);
    protected:
    private:  // methods
      void run(void);
    private:  // attributes
      typedef std::vector<DataReader*> ReaderList;
      typedef std::map<std::string, ReaderList> Map;
      void* sub_;
      Map map_;
  };
#endif
